#We need Bits Transfer cmdlets to perform pre-req downloads
Import-Module BitsTransfer

#Hash of all required prerequisites
#These are the minimum required pre-reqs. 
#SilverLight, SQL 2008 R2 SSRS add-on are not included in this list
$sharePointPreReq = @{
	"commonPreReq" = @{
		"Sync Framework"="http://download.microsoft.com/download/C/9/F/C9F6B386-824B-4F9E-BD5D-F95BB254EC61/Redist/amd64/Microsoft%20Sync%20Framework/Synchronization.msi";
		"MS Chart Controls"="http://download.microsoft.com/download/c/c/4/cc4dcac6-ea60-4868-a8e0-62a8510aa747/MSChart.exe";
		"SQL Native Client"="http://download.microsoft.com/download/3/5/5/35522a0d-9743-4b8c-a5b3-f10529178b8a/sqlncli.msi";
		"SQL Analysis Services"="http://download.microsoft.com/download/b/9/a/b9a78047-d269-4a25-88a1-9c4321d90677/SQLSERVER2008_ASADOMD10.msi";
		"MS Speech Platform run time"="http://download.microsoft.com/download/8/D/F/8DFE3CE7-6424-4801-90C3-85879DE2B3DE/Platform/x64/SpeechPlatformRuntime.msi";
		"Speech Recognition TELE - English"="http://download.microsoft.com/download/E/0/3/E033A120-73D0-4629-8AED-A1D728CB6E34/SR/MSSpeech_SR_en-US_TELE.msi"
	}
	
	"R2" = @{	
		"WCF Fix"="http://download.microsoft.com/download/E/C/7/EC785FAB-DA49-4417-ACC3-A76D26440FC2/Windows6.1-KB976462-v2-x64.msu";
		"Windows Identity Framework"="http://download.microsoft.com/download/D/7/2/D72FD747-69B6-40B7-875B-C2B40A6B2BDD/Windows6.1-KB974405-x64.msu";
		"ADO.NET data Service"="http://download.microsoft.com/download/1/3/C/13CBF47A-15D0-4237-ABFC-ED6E3E3A6520/Windows6.1-KB976127-v6-x64.msu"
	}
	
	"SP2" = @{
		"WCF Fix (SP2)"="http://download.microsoft.com/download/6/8/1/681F5144-4092-489B-87E4-63F05E95079C/Windows6.0-KB976394-x64.msu";
		"Windows Identify Framework (SP2)"="http://download.microsoft.com/download/D/7/2/D72FD747-69B6-40B7-875B-C2B40A6B2BDD/Windows6.0-KB974405-x64.msu";
		"ADO.NET data Service (SP2)"="http://download.microsoft.com/download/D/8/7/D87603D9-2693-473E-AB98-7F76F0390A8E/NDP35SP1-KB976126-v2-x64.exe"
		"PowerShell 2.0"="http://download.microsoft.com/download/2/8/6/28686477-3242-4E96-9009-30B16BED89AF/Windows6.0-KB968930-x64.msu"
	}
}

#Build a template for the confis.XML with some defaults
#We will modify this based on parameters passed to New-SPInstallPackage
[xml]$configXml = 
@"
<Configuration>
	<Logging Type="verbose" Path="%temp%" Template="SharePoint Server Setup(*).log"/>
	<PIDKEY Value="Enter PID Key Here" />
	<Display Level="none" CompletionNotice="no" AcceptEula="no" SuppressModal="yes" NoCancel="yes"/>
	<Setting Id="SERVERROLE" Value="APPLICATION"/>
	<Setting Id="USINGUIINSTALLMODE" Value="0"/>
	<Setting Id="SETUP_REBOOT" Value="Never" />
	<Setting Id="SETUPTYPE" Value="CLEAN_INSTALL"/>
</Configuration>
"@

function Get-SPPreRequisites {
	<#
	.DESCRIPTION
		Download prerequisites for SharePoint 2010 install. You can download these prerequisites files for a 
		specific OS (R2/SP2) or both.
	.SYNOPSIS
		Download prerequisites for SharePoint 2010 install
	.PARAMETER OS
		Specifies OS for which want to download the prerequisites. Valid values are R2 and SP2
	.PARAMETER destination
		A destination folder to download the prerequisite files.
	.PARAMETER all
		Specifies that all prerequisites downloaded irrespective of OS type
	.OUTPUTS
		Returns the status
	.EXAMPLE
		Get-SPPreRequisites -OS "R2" -Destination "C:\SharePoint"
		Get-SPPreRequisites -OS "SP2" -Destination "C:\SharePoint"
		
		Description
		-----------
		The above examples download the SharePoint 2010 prerequisites for a specifc OS
	.EXAMPLE
		Get-SPPreRequisites -All -Destination "C:\SharePoint"
		
		Description
		-----------
		The above example downloads the SharePoint 2010 prerequisites for all applicable OS		
	.LINK
		Online version: http://www.ravichaganti.com/blog
	.LINK
		http://pssp2010utils.codeplex.com
	#>
	[CmdletBinding(DefaultParameterSetName="All+Destination")]
	param (
		[Parameter(ParameterSetName="OS+detination",Mandatory=$false)]
    	[ValidateSet("SP2", "R2")]
    	[String]$os,
		
		[Parameter(ParameterSetName="All+Destination",Mandatory=$true)]
    	[Switch]$all,
		
		[Parameter(ParameterSetName="All+Destination",Mandatory=$True)]
		[Parameter(ParameterSetName="OS+detination",Mandatory=$True)]
		[ValidateScript({(Get-Item $_).PSIsContainer})]
    	[String]$destination
	)
	if (!(Test-Path $destination)) {
		mkdir $destination
	}
	
	#check if we need proxy credentials
	if (!(Test-Proxy)) {
		try {
			Write-Host `n"Provide proxy credentials.." -ForegroundColor Yellow
			$Script:proxyCred = Get-Credential
		}
		catch {
			Write-Error "Error getting credentials"
			return $null
		}
	}
	
	$urls = @{}
	$urls += $sharePointPreReq["commonPreReq"]
	if ($all) {
		$urls += $sharePointPreReq["R2"]
		$urls += $sharePointPreReq["SP2"]
	} else {
		$urls += $sharePointPreReq[$os]
	}
	
	Write-Host -NoNewline -ForegroundColor White "Starting pre-requisite downloads.."
	try {
		foreach ($url in $urls.Keys) {
			if ($Script:proxyCred) {
					Start-BitsTransfer -Source $urls[$url] -Destination $destination -ProxyCredential $Script:proxyCred -ProxyAuthentication Negotiate -Description $url
			} else {
					Start-BitsTransfer -Source $urls[$url] -Destination $destination -Description $url
			}	
		}
	}
	catch {
		Write-Host -ForegroundColor Red "Error"
		return $null
	}
	
	Write-Host -ForegroundColor Green "Done"
	return (Get-Item $destination) | Out-Null
}

#TODO
#1. Add support for more install types other than CLEAN_INSTALL
#2. Add support for supplying a readymade config.xml
function New-SPInstallPackage {
<#
    .DESCRIPTION
        Creates a new SharePoint install package either from an ISO or folder path where the SharePoint install files are stored.
		This also downloads all the prerequisite files from the internet and copies them to the package. A config.XML file will be 
		generated and copied to the package. Also, this will create a SP_Setup.bat at the root of the folder to install all prerequisites
		and SharePoint software at one click.
    .SYNOPSIS
        Creates a SharePoint install package
	.PARAMETER packageName
		Name of the custom install package.
    .PARAMETER AcceptEula
        If specified, eula is automatically accepted. By default, SharePoint install will stop at this screen
	.PARAMETER DisplayLevel
        Display level for the install GUI. Valid values are "none", "basic", "full". Default is "none".
    .PARAMETER ServerRole
        Defines the type of SharePoint server installation. Default is "APPLICATION" and the valid values are "APPLICATION", "WFE", "SINGLESERVER"
    .PARAMETER SetupType
        This parameter specifies what type an install is being performed. At present, this module supports only "CLEAN_INSTALL"
	.PARAMETER LoggingType
        The logging level for the SharePoint install. Valid values are "off", "standard", "verbose". Verbose is the default.
    .PARAMETER LogPath
        Place where all the log files are stored.Default value is %temp%
    .PARAMETER LogTemplate
        This defines the format of the filename of the log. Default value is "SharePoint Setup Log (*).log"   
	.PARAMETER CompletionNotice
        The completion notice will be shown if this switch parameter is specified
    .PARAMETER UseUIInstallMode
       	UI mode will be used for the install, if this switch parameter is specified
    .PARAMETER ShowModalDialogs
        If specified, the modal dialog boxes are shown
    .PARAMETER AllowCancel
        If specified, you will be able to cancel the SP install
    .PARAMETER PIDKey
        PID for the SharePoint product install
	.PARAMETER OS
		OS on which you are performing the SharePoint 2010 install. Valid values are "R2","SP2", and "WIN7"
	.PARAMETER NoZip
		If specified, prevents creation of ZIP file of the new install package.
	.PARAMETER sourceISO
		Path to the SharePoint 2010 ISO file. You will require 7zip installed on the local machine to use this option
	.PARAMETER sourceFolder
		Path to either the SharePoint 2010 DVD drive contents and a folder with these contents
	.PARAMETER packageFolder
		Path to copy the customized SharePoint 2010 install zip package
    .EXAMPLE
        New-SPInstallPackage  -PackageName "SP2010-R2" -PIDKey "11111-22222-33333-44444-55555" -AcceptEula -OS "R2" -sourceISO "C:\SharePoint\SharePointServer.ISO" -packagefolder C:\SharePoint
		
		Description
		-----------
		The above command will extract the SharePoint ISO file, download pre-Req files for R2, copy the config.xml with specified PID & 
		AcceptEula set to yes, and finally creates a zip package to specified folder.
    .EXAMPLE
        New-SPInstallPackage  -PackageName "SP2010-R2" -PIDKey "11111-22222-33333-44444-55555" -AcceptEula -OS "R2" -sourceFolder "C:\SharePoint\SharePointInstallFiles" -PackageFolder C:\SharePoint
		
		Description
		-----------
		The above command will use the extracted SharePoint install files, download pre-Req files for R2, copy the config.xml with specified PID & 
		AcceptEula set to yes, and finally creates a zip package to specified package folder.
    .EXAMPLE
        New-SPInstallPackage -PackageName "SP2010-R2" -PIDKey "11111-22222-33333-44444-55555" -AcceptEula -OS "R2" -sourceFolder "C:\SharePoint\SharePointInstallFiles" -PackageFolder C:\SharePoint -noZip
		
		Description
		-----------
		The above command will use the extracted SharePoint install files, download pre-Req files for R2, copy the config.xml with specified PID & 
		AcceptEula set to yes, and finally copy the customized folder to specified package folder.
	.LINK
        Online Version: http://www.ravichaganti.com/blog
        http://pssp2010utils.codeplex.com
#>
	[CmdletBinding(DefaultParameterSetName="ISO+Options")]
	param
	(
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$true)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$true)]
		[String]$packageName,

		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)]
		[ValidateSet("none", "basic", "full")]
		[String]$DisplayLevel = "none",
		
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)][ValidateSet("off", "standard", "verbose", "debug")]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)][ValidateSet("off", "standard", "verbose", "debug")]
		[String]$LoggingType = "verbose",
	
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)]
		[ValidateNotNullOrEmpty()]
		[String]$LogPath = "%temp%",
	
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)]
		[ValidateNotNullOrEmpty()]
		[String]$LogTemplate = "SharePoint Setup Log (*).log",
	
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)]
		[switch]$CompletionNotice,
	
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)]
		[switch]$UseUIInstallMode,
	
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)]
		[switch]$AcceptEula,
	
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)]
		[switch]$ShowModalDialogs,
	
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)]
		[switch]$AllowCancel,
		
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)]
		[switch]$noZip,
	
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)]
		[ValidateSet("APPLICATION", "WFE", "SINGLESERVER")]
		[String]$ServerRole = "APPLICATION",
	
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$false)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$false)]
		[ValidateSet("CLEAN_INSTALL")]
		[String]$SetupType = "CLEAN_INSTALL",
		
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$true)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$true)]
		[String]$PIDKey,
		
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$true)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$true)]
		[ValidateSet("SP2", "R2", "WIN7")]
		[String]$os,
		
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$true)]
		[ValidateScript({((Get-Item $_).PSIsContainer) -and (Test-Path "$_\setup.exe" -IsValid -PathType Leaf)})]
		[String]$sourceFolder,
		
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$true)]
		[ValidateScript({ if ((Get-Item $_).Extension -eq ".iso") {$true}})]
		[String]$sourceISO,
		
		[Parameter(ParameterSetName="ISO+Options",Mandatory=$true)]
		[Parameter(ParameterSetName="Folder+Options",Mandatory=$true)]
		[ValidateScript({(Get-Item $_).PSIsContainer})]
		[String]$packageFolder
	)
	
	if ($sourceISO) {
		#Extract the ISO, if specified
		#Check if 7z.exe exists in programfiles. If not, abort
		if (Test-Path "$env:ProgramFiles\7-Zip\7z.exe") {
			#create a folder under %temp% and then extract the ISO
			try {
				Write-Host -NoNewline "Starting ISO extract.."
				if (Test-Path "$env:TEMP\SharePoint") {
					Remove-Item "$env:TEMP\SharePoint" -Force -Recurse
					$extractFolder = (mkdir "$env:TEMP\SharePoint")
				} else {
					$extractFolder = (mkdir "$env:TEMP\SharePoint")
				}
				$7zipProcess = [System.Diagnostics.Process]::Start( "$env:ProgramFiles\7-Zip\7z.exe"," x $sourceISO -o$($extractFolder.FullName)" )
				$7zipProcess.WaitForExit()
				if ($7zipProcess.ExitCode -ne 0) {
					Write-Error "There was an error extracing the ISO"
					return $null
				} else {
					Write-Host "Done" -ForegroundColor Green
					$tmpFolder = $extractFolder
				}
			}
			catch {
				Write-Error "There was an error starting 7ZIP process"
				return $null
			}
		} else {
			Write-Error "7-Zip is not found. This is required to extract ISO files"
		}
	} else {
		#Let us just make a copy of $sourceFolder contents to $env:TEMP
		if (Test-Path "$env:TEMP\SharePoint") {
			Remove-Item "$env:TEMP\SharePoint" -Force -Recurse
			mkdir "$env:TEMP\SharePoint" | Out-Null
		} else {
			mkdir "$env:TEMP\SharePoint" | Out-Null
		}
		try {
			Copy-Item "$sourceFolder\*" -Recurse -Destination "$env:temp\SharePoint"
		}
		catch {
			Write-Error "Error copying files to $env:temp\SharePoint"
			return $null
		}
		$tmpFolder = (Get-Item "$env:temp\SharePoint")
	}
		
	#Download the prerequisites to PreRequisiteFiles Folder in the extracted location or specified sourceFolder location
	Write-Host "Downloaing prerequisite files.." -NoNewline
	Try {
		If ($os -eq "R2" -or $os -eq "WIN7") {
			Get-SPPreRequisites -os "R2" -Destination "$($tmpFolder.FullName)\PrerequisiteInstallerFiles"
		} else {
			Get-SPPreRequisites -os $os -Destination "$($tmpFolder.FullName)\PrerequisiteInstallerFiles"
		}
	}
	catch {
		Write-Error "Error Downloading prerequisite files"
		return $null
	}
	Write-Host "Done" -ForegroundColor Green
		
	#Start updating the config.xml with parameters we received
	Write-Host -NoNewline "Generating config.xml.."
	$configXml.Configuration.Display.Level = $DisplayLevel.ToLower()

	if (($CompletionNotice) -and ($configXml.Configuration.Display.Level -ne "Full"))
	{
		$configXml.Configuration.Display.CompletionNotice = "yes"
	}
	
	if (($CompletionNotice) -and ($DisplayLevel -eq "Full"))
	{
		Write-Warning "ShowCompletionNotice is not valid when DisplayLevel is set to full"
	}

	if ($AcceptEULA)
	{
		$configXml.Configuration.Display.AcceptEULA = "yes"
	}

	if (($ShowModalDialogs) -and ($configXml.Configuration.Display.Level -eq "basic"))
	{
		$configXml.Configuration.Display.SuppressModal = "no"
	}
	
	if (($SuppressModal) -and (($DisplayLevel -eq "none") -or ($DisplayLevel -eq "full")))
	{
		Write-Warning ("SuppressModal is not valid when DisplayLevel is set to none or full")
	}

	if (($AllowCancel) -and (($configXml.Configuration.Display.Level -eq "basic") -or ($configXml.Configuration.Display.Level -eq "full")))
	{
		$configXml.Configuration.Display.NoCancel="no"
	}
	
	if (($AllowCancel) -and ($DisplayLevel -eq "none"))
	{
		Write-Warning "AllowCancel is not valid when display level is set to none"
	}

	$configXml.Configuration.Logging.Type = $LoggingType
	$configXml.Configuration.Logging.Template = $LogTemplate
	$configXml.Configuration.Logging.Path = $LogPath

	$ServerRoleSetting = $configXml.Configuration.Setting | ? { $_.Id -eq "SERVERROLE"}
	if ($os -eq "WIN7" ) {
		#Hard Code this. We are doing a single server install if the OS is Windows 7
		$ServerRoleSetting.Value = "SINGLESERVER"
	} else {
		$ServerRoleSetting.Value = $ServerRole.ToUpper()
	}
	$UiInstallModeSetting = $configXml.Configuration.Setting | ? { $_.Id -eq "USINGUIINSTALLMODE"}
	
	if ($UseUIInstallMode)	{
			$UiInstallModeSetting.Value = "1"
	}

	if ($PIDKey) {
			$configXml.Configuration.PIDKEY.Value = $PIDKey
	} else {	
		Write-Error "No PID specified"
		return $null
	}

	#Check if the OS type is Windows 7. In this case we need to add some more information to config.XML
	if ($os -eq "WIN7") {
		$ClientOSNode = $configXml.CreateNode([System.Xml.XmlNodeType]::Element, "Setting", $null);
		$ClientOSNode.SetAttribute("Id", "AllowWindowsClientInstall")
		$ClientOSNode.SetAttribute("Value", "True")
		$configXml.Configuration.AppendChild($ClientOSNode) | Out-Null
	}

	try {
		#save config.xml
		Write-Host "saving config.xml to $($tmpFolder.FullName)\config.xml"
		$newConfigXML = "$($tmpFolder.FullName)\config.xml"
		$configXml.Save($newConfigXML)
	}
	catch {
		Write-Error "Error creating config.xml"
		Return $null
	}
	Write-Host "Done" -ForegroundColor Green
	   
    #Generate prerequites.Arguments.txt and copy to $tmpFolder
    if (!($os -eq "WIN7")) {
		if ($os -eq "R2") {
			Copy-Item .\PrerequisiteInstaller.Arguments.R2 "$($tmpFolder.FullName)\PrerequisiteInstaller.Arguments.txt"
		} else {
			Copy-Item .\PrerequisiteInstaller.Arguments.SP2 "$($tmpFolder.FullName)\PrerequisiteInstaller.Arguments.txt"
		}
	}
	
    #Generate setup_OS batch file
	Copy-Item .\Setup_$os.bat "$($tmpFolder.FullName)"
    
    #Generate Self-Extract ZIP, if required
   	if ($noZip) {
		Rename-Item -Path $tmpFolder -NewName $packageName -Force
		Move-Item -Path $("$($tmpFolder.PSParentPath)\$packageName") -Destination $packageFolder -Force
	} else {
		$archiveName = Join-Path $packageFolder "$($packageName).exe"
		Out-SFX -folder $tmpFolder -zipName $archiveName
	}
}

function Install-SPIFilter {
    <#
        .DESCRIPTION
            Installs an iFilter MSI, updates the DOCICON.XML if an icon file is specified and adds the new file type to
	        Crawl extensions list for a specified search service application
        .SYNOPSIS
            Installs & configures an iFilter for SharePoint 2010
        .PARAMETER IFilterMSI
            Absolute path to an iFilter MSI file
        .PARAMETER FileType
            Extension of the iFilter file type
        .PARAMETER Icon
            Specifies absolute path to the icon file
        .PARAMETER SearchServiceApplicationId
            Specifies the search service application Id
        .OUTPUTS
            Returns the status of every activity in the process
        .EXAMPLE
            Install-SPIFilter -IFilterMSI C:\SP2010\PDFFilterx64Installer.MSI -Icon c:\SP2010\pdf_smallicon.gif -fileType PDF -SearchServiceApplicationId (Get-SPEnterpriseSearchServiceApplication).Id
        
            Description
            -----------
            The above example will install the PDF x64 IFilter, add the icon file to DOCICON.xml and add the crawl extension to search service application
        .EXAMPLE
            Install-SPIFilter -IFilterMSI C:\SP2010\PDFFilterx64Installer.MSI -fileType PDF -SearchServiceApplicationId (Get-SPEnterpriseSearchServiceApplication).Id
        
            Description
            -----------
            The above example will install the PDF x64 IFilter, and adds the crawl extension to search service application
        .LINK
            Online version: http://www.ravichaganti.com/blog
        .LINK
            http://pssp2010utils.codeplex.com
    #>
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [ValidateScript({ if ((Get-Item $_).Extension -eq ".msi") {$true}})]
        [String]$IFilterMSI,
        
        [Parameter(Mandatory=$true)]
       	[String]$filetype,
        
        [Parameter(Mandatory=$false)]
       	[String]$Icon,

        [Parameter(Mandatory=$true)]
       	[String]$SearchServiceApplicationId
    )

    $script:TEMPLATE = $("$env:CommonProgramFiles\Microsoft Shared\Web Server Extensions\14\TEMPLATE")
    
    #Install MSI
    Write-Host
    Write-Host -NoNewline "Installing $IFilterMSI"
    
    try {
        $msiProcess = [System.Diagnostics.process]::Start("msiexec","/i $IFilterMSI /quiet /qn")
        $msiProcess.WaitForExit()
        if ($msiProcess.ExitCode -ne 0) {
            Write-Host -ForegroundColor Red "`t [Error]"
            Return $false
        } else {
            Write-Host -ForegroundColor Green "`t [Done]"
        }
        
    }
    
    catch {
        Write-Error "`nThere was an error starting the install process"
    }
    
    #Add docicon if $icon exists
    if ($icon) {
        Write-Host
        Write-Host -NoNewline "Adding $icon to DOCICON.XML"
        $iconName = (Get-Item $icon).Name
        
        #Copy the icon file to 14 hive
        Copy-Item -Path $icon -Destination $("$Script:TEMPLATE\IMAGES") -Force
        #Create a copy of DOCICON.XML
        Copy-Item -Path "$script:TEMPLATE\XML\DOCICON.XML" -Destination "$script:TEMPLATE\XML\DOCICON.BAK" -Force
        
        #Read XML
        try {
            $xml = New-Object XML
            $xml.Load("$script:TEMPLATE\XML\DOCICON.XML")
            $cloneNode = @($xml.DocIcons.ByExtension.Mapping)[0]
            $newNode = $cloneNode.Clone()
            $newNode.Key = $fileType
            $newNode.Value = $iconName
            $newNode.EditText = $fileType
            $newNode.OpenControl = ""
            $xml.DocIcons.ByExtension.AppendChild($newNode) | Out-Null
            $xml.Save("$script:TEMPLATE\XML\DOCICON.XML")
        }
        catch {
            Write-Error "`nError occurred while loading/manipulating XML"
            return $false
        }
        Write-Host -ForegroundColor Green "`t [Done]"
    }
    
    #Add crawl extension
    Write-Host
    Write-Host -NoNewline "Adding crawl extension"
    try {
        New-SPEnterpriseSearchCrawlExtension -Name $fileType -SearchApplication $SearchServiceApplicationId | Out-Null
    }
    catch {
        Write-Error "`nError occured while adding crawl extension"
        return $false
    }
    Write-Host -ForegroundColor Green "`t [Done]"
    return $true
}

function Install-SPPackage {
	Write-Host "This is not implemented"
}

Function Test-Proxy {
	$webclient = New-Object System.Net.WebClient
	return $webclient.Proxy.IsBypassed("http://www.microsoft.com")
}

Function Out-SFX {
	[CmdletBinding()]
	param
	(
		[Parameter(Mandatory=$true)]
		[System.IO.DirectoryInfo]$folder,

		[Parameter(Mandatory=$true)]
		[String]$zipName
	)
	$7zipProcess = [System.Diagnostics.Process]::Start( "$env:ProgramFiles\7-Zip\7z.exe"," a -sfx $zipName $($folder.FullName)" )
	$7zipProcess.WaitForExit()
	if ($7zipProcess.ExitCode -ne 0) {
		Write-Error "There was an error creating the self-extract zip"
		return $null
	} else {
		Write-Host "Done" -ForegroundColor Green
		return (Get-Item $zipName) | Out-Null
	}
}